import { Injectable } from '@nestjs/common';
import {
  CreateUserDto,
  GetUserDto,
  LoginUserDto,
  UpdateMyPasswordDto,
  UpdatePasswordDto,
  UpdateUserDto,
} from './dto/user.dto';
import { InjectRepository } from '@nestjs/typeorm';
import { User } from 'src/database/user.entity';
import { Repository } from 'typeorm';
import { CommonExpection } from 'src/error';
import { CaptchaService } from './services/captcha.service';
import { PasswordEncryptionService } from 'src/services/password.service';
import { TokenService } from './services/token.service';
import { Request } from 'express';
import { Role } from 'src/database/role.entity';
@Injectable()
export class UserService {
  constructor(
    @InjectRepository(User)
    private userRepository: Repository<User>,
    @InjectRepository(Role)
    private roleRepository: Repository<Role>,
    private readonly captchService: CaptchaService,
    private readonly tokenService: TokenService,
  ) {}
  async create(createUserDto: CreateUserDto) {
    const user = new User();
    for (const key in createUserDto) {
      user[key] = createUserDto[key];
    }
    const role = await this.roleRepository.findOne({
      where: { key: 'sys_admin' },
    });
    user.roles = [role];
    return this.userRepository.save(user);
  }

  async findAll(getUserDto: GetUserDto) {
    const [users, total] = await this.userRepository
      .createQueryBuilder('user')
      .where('user.userName LIKE :userName', {
        userName: `%${getUserDto.userName}%`,
      })
      .skip((getUserDto.page - 1) * getUserDto.pageSize)
      .take(getUserDto.pageSize)
      .getManyAndCount();

    return {
      total,
      list: users,
    };
  }
  // 获取自己的token信息
  async getTokenInfo(token: string) {
    return { id: 33 };
    const res = await this.tokenService.decoded(token);
    return res;
  }

  async findOne(id: number) {
    const res = await this.userRepository.findOne({
      where: { id },
    });
    if (!res) {
      throw new CommonExpection(1001, '用户不存在');
    }
    return res;
  }

  update(id: number, updateUserDto: UpdateUserDto) {
    return this.userRepository.update(id, updateUserDto);
  }

  remove(id: number) {
    return this.userRepository.delete(id);
  }

  getCaptcha() {
    return this.captchService.generateCaptcha();
  }

  async login(body: LoginUserDto, session: Record<string, any>, req: Request) {
    const destory = () => {
      req.session.destroy((err) => {
        console.log(err);
      });
    };
    // 取出正确验证码
    const captcha: string = session.captcha;
    if (!captcha) {
      destory();
      throw new CommonExpection(1002, '验证码已过期');
    }
    // 验证码是否正确
    if (captcha.toLocaleLowerCase() !== body.code.toLocaleLowerCase()) {
      destory();
      throw new CommonExpection(1002, '验证码错误');
    }
    // 查找用户
    const user = await this.userRepository.findOne({
      where: { account: body.account },
      relations: ['roles'],
    });
    if (!user) {
      destory();
      throw new CommonExpection(1003, '用户不存在');
    }
    // 验证密码
    const isPass = PasswordEncryptionService.comparePassword(
      body.password,
      user.password,
    );
    if (!isPass) {
      destory();
      throw new CommonExpection(1004, '密码错误');
    }
    destory();
    // 登录成功，签发token
    return this.tokenService.sign({
      id: user.id,
      account: user.account,
      role: user.roles,
    });
  }

  async findMy(token: string) {
    const user = await this.getTokenInfo(token);
    return this.findOne(user.id);
  }

  // 更改密码
  async updatePassword(body: UpdatePasswordDto) {
    // 查找用户
    const user = await this.userRepository.findOne({ where: { id: body.id } });
    if (!user) {
      throw new CommonExpection(1001, '用户不存在');
    }
    // 验证密码是否正确
    const isPass = await PasswordEncryptionService.comparePassword(
      body.oldPassword,
      user.password,
    );
    if (!isPass) {
      throw new CommonExpection(1004, '密码错误');
    }
    // 修改密码
    const newPassword = await PasswordEncryptionService.encryptPassword(
      body.newPassword,
    );
    return this.userRepository.update(body.id, { password: newPassword });
  }

  // 更新自己密码
  async updateMyPassword(body: UpdateMyPasswordDto, token: string) {
    const user = await this.getTokenInfo(token);
    return this.updatePassword({
      id: user.id,
      oldPassword: body.oldPassword,
      newPassword: body.newPassword,
    });
  }

  // 分配角色
  async assignRole(body: { userId: number; roleIds: number[] }) {
    const roles = await this.roleRepository.findByIds(body.roleIds);
    const user = await this.userRepository.findOne({
      where: { id: body.userId },
    });
    user.roles = roles;
    return this.userRepository.save(user);
  }

  // 获取用户的角色
  async getUserRoles(userId: number) {
    const res = await this.userRepository.findOne({
      where: { id: userId },
      relations: ['roles'],
      select: ['id'],
    });
    return res.roles;
  }
}
